// -*- C++ -*-

// Copyright 2006-2007 Deutsches Forschungszentrum fuer Kuenstliche Intelligenz 
// or its licensors, as applicable.
// 
// You may not use this file except under the terms of the accompanying license.
// 
// Licensed under the Apache License, Version 2.0 (the "License"); you
// may not use this file except in compliance with the License. You may
// obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// Project: roughocr -- mock OCR system exercising the interfaces and useful for testing
// File: ocr-cseg-ccs.cc
// Purpose: attempt to segment a line (or page) of text into characters by labeling the connected components
// Responsible: tmb
// Reviewer: 
// Primary Repository: 
// Web Sites: www.iupr.org, www.dfki.de

#include "colib.h"
#include "imgio.h"
#include "imglib.h"
#include "ocr-utils.h"
#include "ocr-segmentations.h"
#include "bengali.h"

using namespace ocropus;
using namespace imglib;
using namespace colib;

struct BengaliSegmenter : ISegmentLine {
    ~BengaliSegmenter() {}

    const char *description() {
        return "find and mask matra, then segment characters by 1D projection\n";
    }

    void init(const char **argv) {
        // nothing to be done
    }

    void matra_filter(bytearray &image, int rx, int ry) {
        int w = image.dim(0);
        int h = image.dim(1);
        int i, z;

        bytearray temp, temp2;
        makelike(temp, image);
        makelike(temp2, image);
        copy(temp, image);

        // I so do not claim that this is clean code
        for(int j = 0; j < 4; j++) {

            for(int x=0; x<w; x++) {
                for(int y=0; y<h; y++) {
                    temp2(x, y) = temp(x, y);
                    if (temp(x, y)) {
                        z = 1;
                        for(i = (x < rx) ? 0 : x - rx; i < w && i < x; i++) {
                            if (!temp(i, y)) {
                                z = 0;
                                break;
                            }
                        }
                        if (!z) {
                            z = 1;
                            for(i = x + 1; i < w && i < x + rx; i++) {
                                if (!temp(i, y)) {
                                    z = 0;
                                    break;
                                }
                            }
                        }
                        if (!z) {
                            temp2(x, y) = 0;
                        }
                    }
                }
            }
            copy(temp, temp2);

            // put some pixels back
            for(int x = 0; x < w; x++) {
                for(int y = 0; y < h; y++) {
                    for(z = (y < ry) ? 0 : y - ry; z <= y + ry && z < h; z++) {
                        if(temp2(x, z)) {
                            temp(x, y) = image(x, y);
                            break;
                        }
                    }
                }
            }
        }

        copy(image, temp);
        //difference(image, temp, 0, 0);
    }

    void charseg(intarray &image, bytearray &in) {
        param_int swidth("swidth",0,"smearing width");
        param_int sheight("sheight",10,"smearing height");
        bytearray temp, temp2;
        int lastseg = 0;
        copy(image,in);
        copy(temp,in);
        copy(temp2,in);
        matra_filter(temp2, 20, 2);
        difference(temp, temp2, 0, 0);
        //close_rect(temp, swidth, sheight);
        intarray labels;
        copy(labels,temp);
        label_components(labels);
        for(int i=0;i<image.dim(0);i++) {
            for(int j=0; j<image.dim(1);j++) {
                if(image(i, j)) {
                    if(labels(i, j)) {
                        image(i, j) = cseg_pixel(labels(i, j));
                    } else {
                        int k;
                        for(k=0; k<image.dim(1) && !labels(i, k);k++);
                        if (k<image.dim(1)) {
                            image(i, j) = cseg_pixel(labels(i, k));
                            lastseg     = cseg_pixel(labels(i, k));
                        } else {
                            if (lastseg > 0) {
                                image(i, j) = lastseg;
                            } else {
                                image(i, j) = 0;
                            }
                            /*
                            for(k=i; k > 0 && !labels(k, j); k--);
                            if (k > 0) {
                                image(i, j) = cseg_pixel(labels(k, j));
                            } else {
                                image(i, j) = 0;
                            }
                            */
                        }
                    }
                }
            }
        }
        make_line_segmentation_white(image);
        check_line_segmentation(image);
    }
};

namespace ocropus {
    ISegmentLine *make_BengaliSegmenter() {
        return new BengaliSegmenter();
    }
}

